#include <haluart.h>
#include <reguart.h>
#include <halcpuctrl.h>
/*********************************************************************************
* 
* hal_uart0_init - UART0 初始化
* 
* DESCRIPTION
*/

static void hal_uart0_init (void)
    {

    /*
     * UART 0 line control register:
     * (0 << 6) : Normal mode operation
     * (0 << 3) : No parity
     * (0 << 2) : One stop bit per frame
     * (3 << 0) : 8-bits per frame
     */  

    hal_io32_write (S3C2440_REG_ULCON0, (0 << 6) | (0 << 3) | (0 << 2) | (3 << 0));

    /*
     * UART 0 control register:
     * (1 << 2) : Transmit Mode is Interrupt request or polling mode
     * (1 << 0) : Receive Mode is Interrupt request or polling mode
     */     
 
    hal_io32_write (S3C2440_REG_UCON0, (1 << 2) | (1 << 0));

    /*
     * UART 0 FIFO control register:
     * (0 << 0) : FIFO is disabled
     */       
   
    hal_io32_write (S3C2440_REG_UFCON0, (0 << 0));

    /*
     * UART 0 modem control register:
     * (0 << 0) : Request to Send is set as disabled Flow Control
     */      

    hal_io32_write (S3C2440_REG_UMCON0, (0 << 0));

    /*
     * UART 0 baud rate divisor register:
     * (21 << 0) : baud rate is set as 115200 (50000000 / (115200 x 16) - 1 ≈ 26)
     */     

    hal_io32_write (S3C2440_REG_UBRDIV0, 26);

    return;
    }

/*********************************************************************************
* 
* hal_uart_init - 初始化串口
* 
* DESCRIPTION
*/

void hal_uart_init (void)
    {

    /* 初始化串口0 */

    hal_uart0_init ();

    return;
    }

/*********************************************************************************
* 
* hal_uart_write - 串口写数据
* 
* DESCRIPTION
*/

drvstus_t hal_uart_write 
    (
    uint_t uart, 
    void * buf, 
    uint_t len
    )
    {
    char_t * p = buf;
    cpuflg_t cpuflg;

    /* 关闭中断 */

    irq_disable_savecpuflg (&cpuflg);

    while (*p)
        {
        if (hal_uart_send_char (uart, *p) == ERROR)
            {
            hal_system_is_die ("write uart err");
            return ERROR;
            }
        
        p++;
        }

    /* 开启中断 */

    irq_enable_restcpuflg (&cpuflg);

    return OK;
    }

/*********************************************************************************
* 
* hal_uart_read - 串口读数据
* 
* DESCRIPTION
*/

drvstus_t hal_uart_read 
    (
    uint_t   uart, 
    void *   buf, 
    uint_t * len
    )
    {
    return OK;
    }

/*********************************************************************************
* 
* hal_uart_ioctrl - 串口 IOCTRL
* 
* DESCRIPTION
*/

drvstus_t hal_uart_ioctrl 
    (
    uint_t uart, 
    uint_t ctrlcode, 
    void * ctrldata
    )
    {
    return OK;
    }

/*********************************************************************************
* 
* hal_uart_send_char - 串口发送一个字符
* 
* DESCRIPTION
*/

drvstus_t hal_uart_send_char 
    (
    uint_t uart, 
    char_t ch
    )
    {
    uint_t timeout = 0;

    /* 判断是不是指定串口 */

    if (uart != 0)
        {
        return ERROR;
        }

    /*
     * UART 0 Tx/Rx status register:
     * (1 << 2) : Transmitter is empty
     */

    while ((hal_io32_read (S3C2440_REG_UTRSTAT0) & (1 << 2)) != 1)
        {

        if (timeout > 0x100000)
            {
            return ERROR;
            }

        timeout++;
        }

    /*
     * UART 0 transmission hold register:
     * 0xxx : Transmit data
     */    

    hal_io32_write (S3C2440_REG_UTXH0, ch);
    
    return OK;
    }

/*********************************************************************************
* 
* hal_uart_recv_char - 串口接收一个字符
* 
* DESCRIPTION
*/

drvstus_t hal_uart_recv_char 
    (
    uint_t   uart, 
    char_t * ch
    )
    {
    return OK;
    }
